/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ds_semetralka;

import entities.Faculty;
import entities.Person;
import entities.Professor;
import entities.Program;
import entities.Student;
import entities.Subject;
import entities.University;
import java.util.ArrayList;
import java.util.Random;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

/**
 *
 * @author Admin
 */
public class Generator {

    private EntityManagerFactory emf;
    private EntityManager em;
    private EntityTransaction tx;

    public Generator() {
        emf = Persistence.createEntityManagerFactory("persistence");
        em = emf.createEntityManager();
        tx = em.getTransaction();
    }

    public void generate() {

        University cvut = new University("CVUT", "Praha");

        tx.begin();
        em.persist(cvut);
        tx.commit();

        Faculty fel = new Faculty("Fakulta elektrotechnicka", "Technicka 2");
        Faculty fit = new Faculty("Fakulta informacnich technologii", "Kolejni 550/2");
        Faculty fs = new Faculty("Fakulta strojni", "Technicka 4");

        ArrayList<Faculty> faculties = new ArrayList<Faculty>();

        faculties.add(fel);
        faculties.add(fit);
        faculties.add(fs);

        cvut.setFaculties(faculties);

        for (Faculty faculty : faculties) {
            faculty.setUniversity(cvut);
        }

        tx.begin();
        em.persist(cvut);
        em.persist(fel);
        em.persist(fit);
        em.persist(fs);
        tx.commit();

        Program oi = new Program("Otevrena Informatika");
        Program kyr = new Program("Kybernetika a Robotika");

        Program si = new Program("Softwarove inzenyrstvi");
        Program ti = new Program("Teoreticka informatika");

        Program str = new Program("Strojirenstvi");

        ArrayList<Program> felPrograms = new ArrayList<Program>();
        ArrayList<Program> fitPrograms = new ArrayList<Program>();
        ArrayList<Program> fsPrograms = new ArrayList<Program>();

        felPrograms.add(oi);
        felPrograms.add(kyr);

        fitPrograms.add(si);
        fitPrograms.add(ti);

        fsPrograms.add(str);

        fel.setPrograms(felPrograms);
        fit.setPrograms(fitPrograms);
        fs.setPrograms(fsPrograms);

        for (Program program : fsPrograms) {
            program.setFaculty(fs);
        }

        for (Program program : fitPrograms) {
            program.setFaculty(fit);
        }

        for (Program program : felPrograms) {
            program.setFaculty(fel);
        }

        tx.begin();

        for (Program program : fsPrograms) {
            em.persist(program);
        }

        for (Program program : fitPrograms) {
            em.persist(program);
        }

        for (Program program : felPrograms) {
            em.persist(program);
        }

        for (Faculty faculty : faculties) {
            em.persist(faculty);
        }
        tx.commit();

        ArrayList<Student> oiStudents = generateStudents();
        ArrayList<Student> kyrStudents = generateStudents();

        ArrayList<Student> siStudents = generateStudents();
        ArrayList<Student> tiStudents = generateStudents();

        ArrayList<Student> strStudents = generateStudents();

        for (Student student : oiStudents) {
            student.setProgram(oi);
        }
        for (Student student : kyrStudents) {
            student.setProgram(kyr);
        }
        for (Student student : siStudents) {
            student.setProgram(si);
        }
        for (Student student : tiStudents) {
            student.setProgram(ti);
        }
        for (Student student : strStudents) {
            student.setProgram(str);
        }

        oi.setStudents(oiStudents);
        kyr.setStudents(kyrStudents);
        si.setStudents(siStudents);
        ti.setStudents(tiStudents);
        str.setStudents(strStudents);

        tx.begin();
        for (Program program : fsPrograms) {
            em.persist(program);
        }

        for (Program program : fitPrograms) {
            em.persist(program);
        }

        for (Program program : felPrograms) {
            em.persist(program);
        }
        for (Student student : oiStudents) {
            em.persist(student);
        }
        for (Student student : kyrStudents) {
            student.setProgram(kyr);
        }
        for (Student student : siStudents) {
            em.persist(student);
        }
        for (Student student : tiStudents) {
            em.persist(student);
        }
        for (Student student : strStudents) {
            em.persist(student);
        }
        tx.commit();

        ArrayList<Subject> oiSubjects = new ArrayList<Subject>();

        oiSubjects.add(new Subject("Linearni Algebra", 300, (short) 7));
        oiSubjects.add(new Subject("Diskretni Matematika", 250, (short) 7));
        oiSubjects.add(new Subject("Programovani 1", 250, (short) 6));
        oiSubjects.add(new Subject("Reseni Problemu a Hry", 250, (short) 6));
        oiSubjects.add(new Subject("Logika a Grafy", 250, (short) 5));


        ArrayList<Subject> kyrSubjects = new ArrayList<Subject>();

        kyrSubjects.add(new Subject("Kybernetika", 200, (short) 6));
        kyrSubjects.add(new Subject("Robotika", 200, (short) 7));
        kyrSubjects.add(new Subject("Matematika 1", 300, (short) 8));
        kyrSubjects.add(new Subject("Elektricke Obvody", 250, (short) 6));
        kyrSubjects.add(new Subject("Umela Inteligence", 150, (short) 5));

        ArrayList<Subject> siSubjects = new ArrayList<Subject>();

        siSubjects.add(new Subject("Matematicka Analyza", 300, (short) 8));
        siSubjects.add(new Subject("Softwarove Inzenyrstvi", 250, (short) 7));
        siSubjects.add(new Subject("Architektura Pocitacu", 250, (short) 8));
        siSubjects.add(new Subject("Databazove Systemy", 250, (short) 6));
        siSubjects.add(new Subject("Ekonomika", 250, (short) 5));

        ArrayList<Subject> tiSubjects = new ArrayList<Subject>();

        tiSubjects.add(new Subject("Teorie Informace", 200, (short) 8));
        tiSubjects.add(new Subject("Automaty a Gramatiky", 250, (short) 7));
        tiSubjects.add(new Subject("Struktura Pocitacovych Systemu", 250, (short) 8));
        tiSubjects.add(new Subject("Architektura Softwarovych Systemu", 250, (short) 6));
        tiSubjects.add(new Subject("Anglicky Jazyk", 250, (short) 5));

        ArrayList<Subject> strSubjects = new ArrayList<Subject>();

        strSubjects.add(new Subject("Technicke Kresleni", 200, (short) 6));
        strSubjects.add(new Subject("Fyzika 1", 250, (short) 7));
        strSubjects.add(new Subject("Mechanika", 250, (short) 8));
        strSubjects.add(new Subject("Dynamicke Systemy", 250, (short) 6));
        strSubjects.add(new Subject("Historie Techniky", 250, (short) 5));

        ArrayList<Subject> felSubjects = new ArrayList<Subject>();

        felSubjects.addAll(oiSubjects);
        felSubjects.addAll(kyrSubjects);

        ArrayList<Subject> fitSubjects = new ArrayList<Subject>();

        fitSubjects.addAll(siSubjects);
        fitSubjects.addAll(tiSubjects);

        ArrayList<Subject> fsSubjects = new ArrayList<Subject>();

        fsSubjects.addAll(strSubjects);

        fel.setSubjects(felSubjects);
        fit.setSubjects(fitSubjects);
        fs.setSubjects(fsSubjects);

        for (Subject subject : fsSubjects) {
            subject.setFaculty(fs);
        }

        for (Subject subject : fitSubjects) {
            subject.setFaculty(fit);
        }

        for (Subject subject : felSubjects) {
            subject.setFaculty(fel);
        }

        tx.begin();
        for (Subject subject : fsSubjects) {
            em.persist(subject);
        }

        for (Subject subject : fitSubjects) {
            em.persist(subject);
        }

        for (Subject subject : felSubjects) {
            em.persist(subject);
        }

        em.persist(fel);
        em.persist(fit);
        em.persist(fs);

        tx.commit();

        Random rand = new Random();

        for (Student student : oiStudents) {
            int position1 = rand.nextInt(felSubjects.size());
            int position2 = rand.nextInt(felSubjects.size());

            while (position1 == position2) {
                position1 = rand.nextInt(felSubjects.size());
            }

            student.addSubject(felSubjects.get(position1));
            student.addSubject(felSubjects.get(position2));
            felSubjects.get(position1).addStudent(student);
            felSubjects.get(position2).addStudent(student);
        }

        for (Student student : kyrStudents) {
            int position1 = rand.nextInt(felSubjects.size());
            int position2 = rand.nextInt(felSubjects.size());

            while (position1 == position2) {
                position1 = rand.nextInt(felSubjects.size());
            }

            student.addSubject(felSubjects.get(position1));
            student.addSubject(felSubjects.get(position2));
            felSubjects.get(position1).addStudent(student);
            felSubjects.get(position2).addStudent(student);
        }

        for (Student student : siStudents) {
            int position1 = rand.nextInt(fitSubjects.size());
            int position2 = rand.nextInt(fitSubjects.size());

            while (position1 == position2) {
                position1 = rand.nextInt(fitSubjects.size());
            }

            student.addSubject(fitSubjects.get(position1));
            student.addSubject(fitSubjects.get(position2));
            fitSubjects.get(position1).addStudent(student);
            fitSubjects.get(position2).addStudent(student);
        }

        for (Student student : tiStudents) {
            int position1 = rand.nextInt(fitSubjects.size());
            int position2 = rand.nextInt(fitSubjects.size());

            while (position1 == position2) {
                position1 = rand.nextInt(fitSubjects.size());
            }

            student.addSubject(fitSubjects.get(position1));
            student.addSubject(fitSubjects.get(position2));
            fitSubjects.get(position1).addStudent(student);
            fitSubjects.get(position2).addStudent(student);
        }

        for (Student student : strStudents) {
            int position1 = rand.nextInt(fsSubjects.size());
            int position2 = rand.nextInt(fsSubjects.size());

            while (position1 == position2) {
                position1 = rand.nextInt(fsSubjects.size());
            }

            student.addSubject(fsSubjects.get(position1));
            student.addSubject(fsSubjects.get(position2));
            fsSubjects.get(position1).addStudent(student);
            fsSubjects.get(position2).addStudent(student);
        }

        tx.begin();
        for (Subject subject : fsSubjects) {
            em.persist(subject);
        }

        for (Subject subject : fitSubjects) {
            em.persist(subject);
        }

        for (Subject subject : felSubjects) {
            em.persist(subject);
        }
        for (Student student : oiStudents) {
            em.persist(student);
        }
        for (Student student : kyrStudents) {
            student.setProgram(kyr);
        }
        for (Student student : siStudents) {
            em.persist(student);
        }
        for (Student student : tiStudents) {
            em.persist(student);
        }
        for (Student student : strStudents) {
            em.persist(student);
        }
        tx.commit();

        ArrayList<Professor> felProfessors = generateProfessors();
        ArrayList<Professor> fitProfessors = generateProfessors();
        ArrayList<Professor> fsProfessors = generateProfessors();

        ArrayList<Faculty> felList = new ArrayList<Faculty>();
        felList.add(fel);
        fel.setProfessors(felProfessors);
        for (Professor professor : felProfessors) {
            professor.setFaculties(felList);
        }

        ArrayList<Faculty> fitList = new ArrayList<Faculty>();
        fitList.add(fit);
        fit.setProfessors(fitProfessors);
        for (Professor professor : fitProfessors) {
            professor.setFaculties(fitList);
        }

        ArrayList<Faculty> fsList = new ArrayList<Faculty>();
        fsList.add(fs);
        fs.setProfessors(fsProfessors);
        for (Professor professor : fsProfessors) {
            professor.setFaculties(fsList);
        }


        for (int i = 0; i < felSubjects.size(); i++) {
            int position1 = rand.nextInt(felProfessors.size());
            int position2 = rand.nextInt(fitProfessors.size());
            int position3 = rand.nextInt(felProfessors.size());
            int position4 = rand.nextInt(fitProfessors.size());

            felSubjects.get(i).setSupervisor(felProfessors.get(position1));
            fitSubjects.get(i).setSupervisor(fitProfessors.get(position2));

            felSubjects.get(i).addProfessor(felProfessors.get(position3));
            fitSubjects.get(i).addProfessor(fitProfessors.get(position4));

            felProfessors.get(position1).addSupervisedSubject(felSubjects.get(i));
            fitProfessors.get(position2).addSupervisedSubject(fitSubjects.get(i));
            
            felProfessors.get(position3).addSubject(felSubjects.get(i));
            fitProfessors.get(position4).addSubject(fitSubjects.get(i));

        }

        for (int i = 0; i < fsSubjects.size(); i++) {
            int position1 = rand.nextInt(fsProfessors.size());
            int position2 = rand.nextInt(fsProfessors.size());

            fsSubjects.get(i).setSupervisor(fsProfessors.get(position1));
            fsSubjects.get(i).addProfessor(fsProfessors.get(position2));

            fsProfessors.get(position1).addSupervisedSubject(fsSubjects.get(i));
            fsProfessors.get(position2).addSubject(fsSubjects.get(i));

        }

        tx.begin();
        for (Professor professor : fsProfessors) {
            em.persist(professor);
        }
        for (Professor professor : felProfessors) {
            em.persist(professor);
        }
        for (Professor professor : fitProfessors) {
            em.persist(professor);
        }
        for (Subject subject : fsSubjects) {
            em.persist(subject);
        }

        for (Subject subject : fitSubjects) {
            em.persist(subject);
        }

        for (Subject subject : felSubjects) {
            em.persist(subject);
        }
        tx.commit();

    }

    private ArrayList<Student> generateStudents() {
        ArrayList<Student> students = new ArrayList<Student>();
        Random rand = new Random();

        ArrayList<String> firstNames = new ArrayList<String>();

        firstNames.add("Josef");
        firstNames.add("Karel");
        firstNames.add("Jiri");
        firstNames.add("Martin");
        firstNames.add("Robert");
        firstNames.add("Ales");
        firstNames.add("Tomas");
        firstNames.add("Vlastimil");
        firstNames.add("Mirek");
        firstNames.add("Ondra");

        ArrayList<String> lastNames = new ArrayList<String>();

        lastNames.add("Novak");
        lastNames.add("Harant");
        lastNames.add("Stejskal");
        lastNames.add("Ruzicka");
        lastNames.add("Burianek");
        lastNames.add("Cermak");
        lastNames.add("Lenger");
        lastNames.add("Musil");
        lastNames.add("Fifik");
        lastNames.add("Milichovsky");
        lastNames.add("Vasicek");
        lastNames.add("Vokoun");

        Person[] persons = new Person[20];

        for (int i = 0; i < persons.length; i++) {
            persons[i] = new Person("1234", firstNames.get(rand.nextInt(firstNames.size())), lastNames.get(rand.nextInt(lastNames.size())));
            Student st = new Student();
            st.setPerson(persons[i]);
            students.add(st);
            persons[i].setStudent(st);
        }

        tx.begin();
        for (int i = 0; i < persons.length; i++) {
            em.persist(persons[i]);
        }
        for (Student stud : students) {
            em.persist(stud);
        }

        tx.commit();

        return students;
    }

    private ArrayList<Professor> generateProfessors() {
        ArrayList<Professor> professors = new ArrayList<Professor>();
        Random rand = new Random();

        ArrayList<String> firstNames = new ArrayList<String>();

        firstNames.add("Josef");
        firstNames.add("Karel");
        firstNames.add("Jiri");
        firstNames.add("Martin");
        firstNames.add("Robert");
        firstNames.add("Ales");
        firstNames.add("Tomas");
        firstNames.add("Vlastimil");
        firstNames.add("Mirek");
        firstNames.add("Ondra");

        ArrayList<String> lastNames = new ArrayList<String>();

        lastNames.add("Novak");
        lastNames.add("Harant");
        lastNames.add("Stejskal");
        lastNames.add("Ruzicka");
        lastNames.add("Burianek");
        lastNames.add("Cermak");
        lastNames.add("Lenger");
        lastNames.add("Musil");
        lastNames.add("Fifik");
        lastNames.add("Milichovsky");
        lastNames.add("Vasicek");
        lastNames.add("Vokoun");

        Person[] persons = new Person[5];

        for (int i = 0; i < persons.length; i++) {
            persons[i] = new Person("1234", firstNames.get(rand.nextInt(firstNames.size())), lastNames.get(rand.nextInt(lastNames.size())));
            Professor prof = new Professor();
            prof.setPerson(persons[i]);
            professors.add(prof);
            persons[i].setProfessor(prof);
        }

        tx.begin();
        for (int i = 0; i < persons.length; i++) {
            em.persist(persons[i]);
        }
        for (Professor professor : professors) {
            em.persist(professor);
        }

        tx.commit();

        return professors;
    }
}
